package com.kexio.file.mapper;

import java.time.LocalDateTime;
import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kexio.file.entity.FileInfo;

/**
 * 文件信息数据访问层
 * 
 * 基于MyBatis Plus的文件信息数据访问接口，提供：
 * - 基础CRUD操作（继承自BaseMapper）
 * - 文件查询和检索
 * - 文件统计和分析
 * - 业务关联查询
 * - 多租户数据隔离
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Mapper
public interface FileInfoMapper extends BaseMapper<FileInfo> {
    
    // ==================== 文件查询 ====================
    
    /**
     * 根据业务键查询文件
     * 
     * @param businessKey 业务键
     * @param tenantId 租户ID（可选）
     * @return 文件信息列表
     */
    List<FileInfo> selectByBusinessKey(@Param("businessKey") String businessKey, 
                                       @Param("tenantId") String tenantId);
    
    /**
     * 根据业务类型查询文件
     * 
     * @param businessType 业务类型
     * @param tenantId 租户ID（可选）
     * @return 文件信息列表
     */
    List<FileInfo> selectByBusinessType(@Param("businessType") String businessType, 
                                        @Param("tenantId") String tenantId);
    
    /**
     * 根据内容哈希查询文件（用于去重）
     * 
     * @param contentMd5 MD5哈希值
     * @param contentSha256 SHA256哈希值（可选）
     * @param tenantId 租户ID（可选）
     * @return 文件信息
     */
    FileInfo selectByContentHash(@Param("contentMd5") String contentMd5, 
                                 @Param("contentSha256") String contentSha256,
                                 @Param("tenantId") String tenantId);
    
    /**
     * 根据上传者查询文件
     * 
     * @param uploaderId 上传者ID
     * @param tenantId 租户ID（可选）
     * @param page 分页参数
     * @return 分页结果
     */
    IPage<FileInfo> selectByUploader(@Param("uploaderId") String uploaderId, 
                                     @Param("tenantId") String tenantId,
                                     IPage<FileInfo> page);
    
    /**
     * 根据文件类型查询文件
     * 
     * @param mimeTypePattern MIME类型模式（如 'image/%'）
     * @param tenantId 租户ID（可选）
     * @param page 分页参数
     * @return 分页结果
     */
    IPage<FileInfo> selectByMimeType(@Param("mimeTypePattern") String mimeTypePattern, 
                                     @Param("tenantId") String tenantId,
                                     IPage<FileInfo> page);
    
    // ==================== 文件统计 ====================
    
    /**
     * 统计用户文件数量
     * 
     * @param uploaderId 上传者ID
     * @param tenantId 租户ID（可选）
     * @return 文件数量
     */
    Long countByUploader(@Param("uploaderId") String uploaderId, 
                         @Param("tenantId") String tenantId);
    
    /**
     * 统计用户文件总大小
     * 
     * @param uploaderId 上传者ID
     * @param tenantId 租户ID（可选）
     * @return 文件总大小（字节）
     */
    Long sumFileSizeByUploader(@Param("uploaderId") String uploaderId, 
                               @Param("tenantId") String tenantId);
    
    /**
     * 统计业务类型文件数量
     * 
     * @param businessType 业务类型
     * @param tenantId 租户ID（可选）
     * @return 文件数量
     */
    Long countByBusinessType(@Param("businessType") String businessType, 
                             @Param("tenantId") String tenantId);
    
    /**
     * 统计过期文件数量
     * 
     * @param expireTime 过期时间点
     * @param tenantId 租户ID（可选）
     * @return 过期文件数量
     */
    Long countExpiredFiles(@Param("expireTime") LocalDateTime expireTime, 
                           @Param("tenantId") String tenantId);
    
    // ==================== 文件维护 ====================
    
    /**
     * 查询过期文件
     * 
     * @param expireTime 过期时间点
     * @param tenantId 租户ID（可选）
     * @param limit 限制数量
     * @return 过期文件列表
     */
    List<FileInfo> selectExpiredFiles(@Param("expireTime") LocalDateTime expireTime, 
                                      @Param("tenantId") String tenantId,
                                      @Param("limit") Integer limit);
    
    /**
     * 查询长时间未访问的文件
     * 
     * @param lastAccessBefore 最后访问时间之前
     * @param tenantId 租户ID（可选）
     * @param limit 限制数量
     * @return 文件列表
     */
    List<FileInfo> selectUnusedFiles(@Param("lastAccessBefore") LocalDateTime lastAccessBefore, 
                                     @Param("tenantId") String tenantId,
                                     @Param("limit") Integer limit);
    
    /**
     * 更新文件访问统计
     * 
     * @param fileId 文件ID
     * @param accessTime 访问时间
     * @param incrementAccess 是否增加访问次数
     * @param incrementDownload 是否增加下载次数
     * @return 更新行数
     */
    int updateAccessStats(@Param("fileId") String fileId, 
                          @Param("accessTime") LocalDateTime accessTime,
                          @Param("incrementAccess") boolean incrementAccess,
                          @Param("incrementDownload") boolean incrementDownload);
    
    /**
     * 批量更新文件状态
     * 
     * @param fileIds 文件ID列表
     * @param status 新状态
     * @param updateBy 更新者
     * @return 更新行数
     */
    int batchUpdateStatus(@Param("fileIds") List<String> fileIds, 
                          @Param("status") Integer status,
                          @Param("updateBy") String updateBy);
    
    // ==================== 复杂查询 ====================
    
    /**
     * 搜索文件（支持多条件组合）
     * 
     * @param keyword 关键词（文件名模糊匹配）
     * @param businessType 业务类型（可选）
     * @param mimeTypePattern MIME类型模式（可选）
     * @param uploaderId 上传者ID（可选）
     * @param startTime 开始时间（可选）
     * @param endTime 结束时间（可选）
     * @param minSize 最小文件大小（可选）
     * @param maxSize 最大文件大小（可选）
     * @param status 状态（可选）
     * @param tenantId 租户ID（可选）
     * @param page 分页参数
     * @return 分页结果
     */
    IPage<FileInfo> searchFiles(@Param("keyword") String keyword,
                                @Param("businessType") String businessType,
                                @Param("mimeTypePattern") String mimeTypePattern,
                                @Param("uploaderId") String uploaderId,
                                @Param("startTime") LocalDateTime startTime,
                                @Param("endTime") LocalDateTime endTime,
                                @Param("minSize") Long minSize,
                                @Param("maxSize") Long maxSize,
                                @Param("status") Integer status,
                                @Param("tenantId") String tenantId,
                                IPage<FileInfo> page);
}
